<?php

namespace App\Http\Controllers\Frontend\V10\Auth;

use App\Constant\SmsTemplate;
use App\Constants\RedisKey;
use App\Exceptions\GeneralException;
use App\Facades\CommonPlatformRequestFacade;
use App\Facades\SamLogFacade;
use App\Http\Controllers\Controller;
use App\Http\Requests\Frontend\V10\Auth\RegisterRequest;
use App\Http\Requests\Frontend\V10\Auth\SmsRequest;
use App\Http\Requests\Frontend\V10\Auth\WebRegisterRequest;
use App\Http\Requests\Frontend\V10\Auth\WebSmsRequest;
use App\Library\String\Strings;
use App\Library\Tools\ImageCode;
use App\Models\User;
use App\Models\UserGlobal;
use function Complex\add;
use Exception;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redis;

class RegisterController extends Controller
{
    /**
     * Description:注册
     * Author: Sam
     * DateTime: 2019/1/6 14:23
     * @param RegisterRequest $request
     * @return mixed
     * @throws Exception
     */
    public function register(RegisterRequest $request)
    {
        $params = $this->extractInputFromRules($request, $request->rules());
        $params['source'] = $request->get('source',0);
        $params['is_web'] = $request->get('is_web',0);
        $verify = verifyPhoneCode($params['phone_num'], $params['code']);
        if ($verify) {
            unset($params['code']);
        } else {
            if(array_key_exists('is_web', $params) && $params['is_web'] == 1){
                $redis_key = sprintf(RedisKey::VERIFY_CODE_ERROR,$params['phone_num']);
                Redis::setex($redis_key,600,time());
            }
            return failed('验证码错误');
        }
        $user = User::createUser($params);
        $token = auth('api')->tokenById($user->id);
        UserGlobal::jpushDataUpdate($user, $request); //极光相关更新
        //覆盖Redis中该用户已有的token，使同用户其他设备登录状态失效
        User::updateTokenRecord($user, $token);
        return success([
            'user' => User::getCurrentUserDetailByApp($user),
            'token' => $token,
        ], [], '注册成功');
    }

    /**
     * Description:发送验证码短信
     * Author: Sam
     * DateTime: 2019-03-22 15:44
     * @param SmsRequest $request
     * @return mixed
     * @throws GeneralException
     * @throws \GuzzleHttp\Exception\GuzzleException
     * @throws \Psr\SimpleCache\InvalidArgumentException
     */
    public function sms(SmsRequest $request)
    {
        $phone = $request->get('phone_num');
        $code = Strings::randomCode();
        $exists = Cache::get('send_' . $phone);
        if ($exists) {
            return failed('验证码已生成，请等待');
        }
        $res = CommonPlatformRequestFacade::sms($phone, SmsTemplate::TEMPLATE_REGISTER, ['validCode' => strval($code)]);
        if ($res['code'] === '01') {
            Cache::delete($phone . '_code');
            Cache::add('send_' . $phone, $res['message'], 1);
            Cache::add($phone . '_code', $code, 10);
            return success([], [], '发送成功');
        } else {
            SamLogFacade::debug("发送验证码接口错误：{$res['message']}");
            return failed('发送失败');
        }
    }

    /**
     * Description:web页面发送验证码
     * Author: Sam
     * DateTime: 2019-03-22 15:44
     * @param WebSmsRequest $request
     * @return mixed
     * @throws GeneralException
     * @throws \GuzzleHttp\Exception\GuzzleException
     * @throws \Psr\SimpleCache\InvalidArgumentException
     */
    public function webSms(WebSmsRequest $request)
    {
        $phone = $request->get('phone_num');
        $redis_key =  sprintf(RedisKey::SEND_CODE_TIMES, $phone);
        if(!Redis::exists($redis_key)){
            Redis::setex($redis_key, 300, 0);
        }
        $send_code_times = Redis::get($redis_key);
        if($send_code_times >= 1){
            return failed('',Response::HTTP_FOUND);//需要验证图形验证码
        }
        $unique = User::where('phone_num',$phone)->first();
        if($unique){
            return success([
                'exists'=>1
            ],[],'您已经注册过了');
        }
        $code = Strings::randomCode();
        $exists = Redis::get('send_' . $phone);
        // 需要验证
        if ($exists) {
            $sec = (int)(time() - $exists);
            return failed('验证码已下发，请等待' . '|' . $sec);
        }
        $res = CommonPlatformRequestFacade::sms($phone, SmsTemplate::TEMPLATE_REGISTER, ['validCode' => strval($code)]);
        if ($res['code'] === '01') {
            Cache::delete($phone . '_code');

            // 已发送标识 30秒
            Redis::setex('send_' . $phone, 30, time());

            // 记录给手机号发送的code
            Cache::add($phone . '_code', $code, 10);

            // 记录手机号发送次数
            Redis::incr($redis_key);

            return success(['exists'=>0], [], '发送成功');
        } else {
            SamLogFacade::debug("发送验证码接口错误：{$res['message']}");
            return failed('发送失败');
        }
    }

    /**
     * Description:h5端单独验证验证码
     * Author: cg
     * DateTime: 2019-03-15 17:20
     * @param Request $request
     * @return mixed
     */
    public function webVerifyCode(Request $request)
    {
        $phone = $request->get('phone');
        $code = $request->get('code', 0);
        $isFail = verifyPhoneCode($phone, $code);
        if(!$isFail){
//            $redis_key = sprintf(RedisKey::VERIFY_CODE_ERROR,$phone);
//            Redis::setex($redis_key,60,time());
            return failed('验证码错误');
        }
        return success([]);
    }

    /**
     * Description:h5端先验证再注册
     * Author: cg
     * DateTime: 2019-03-15 17:20
     * @param WebRegisterRequest $request
     * @return mixed
     * @throws GeneralException
     */
    public function webRegister(WebRegisterRequest $request)
    {
        $params = $this->extractInputFromRules($request, $request->rules());

        $params['source'] = $request->get('source',0);
        $params['phone_num'] = $request->get('phone_num',0);
        $params['password'] = $request->get('password',0);
        $user = User::createUser($params);
        $token = auth('api')->tokenById($user->id);
        UserGlobal::jpushDataUpdate($user, $request); //极光相关更新
        //覆盖Redis中该用户已有的token，使同用户其他设备登录状态失效
        User::updateTokenRecord($user, $token);
        return success([
            'user' => User::getCurrentUserDetailByApp($user),
            'token' => $token,
        ], [], '注册成功');
    }

    /**
     * Description:生成图形验证码
     * Author: Sam
     * DateTime: 2019-03-13 17:27
     * @param Request $request
     * @return mixed
     */
    public function createImgCode(Request $request)
    {
        $phone = $request->get('phone');
        if(!$phone){
            return failed('参数错误');
        }
        $code = new ImageCode();
        return $code->createImg($phone);
    }

    /**
     * Description:验证图形验证码结果
     * Author: Sam
     * DateTime: 2019-03-13 17:29
     * @param Request $request
     * @return mixed
     */
    public function verifyImgCode(Request $request){
        $phone = $request->get('phone');
        $redis_key = sprintf(RedisKey::SEND_CODE_TIMES, $phone);
        if(Redis::get($redis_key)){
            Redis::del($redis_key);
            return success([]);
        }else{
            return failed('验证失败');
        }
    }
}